<?php

namespace App\Kuafu\Pay\Channel\WxPay\ApiV2;

use App\Kuafu\Pay\Service\PayConfigService;

/**
 * api v2版本的微信接口
 * Class WxPayApiV2
 * @package App\Kuafu\Pay\WxPay
 */
class WxPayApiV2Base
{
    const API_ENDPOINT        = 'https://api.mch.weixin.qq.com/';
    const SIGNTYPE_MD5        = 'MD5';
    const SIGNTYPE_HMACSHA256 = 'HMAC-SHA256';

    protected $config;

    public function __construct(array $payConfig)
    {
        $this->config = [
            'mch_id'        => $payConfig['mch_id'], //商户号
            'app_id'        => config('pay.wx.official.app_id'), // 公众号的APPID
            'api_key'       => $payConfig['api_key_v2'], //支付密钥
            'ssl_cert_path' => $payConfig['ssl_cert_path'],
            'ssl_key_path'  => $payConfig['ssl_key_path'],
            'sign_type'     => 'MD5',
            'notify_url'    => config('pay.wx.notify_url.pay'),
//            'refund_notify_url' => '',
//            'h5_scene_info'     => [//required in H5
//                'h5_info' => ['type' => 'Wap', 'wap_url' => 'http://wapurl', 'wap_name' => 'wapname']
//            ],
//            'rsa_pubkey_path'   => config('pay.wx.rsa_pubkey_path'),
//            'jsapi_ticket'      => __DIR__ .'/jsapi_ticket.json' //jsticket的临时存放路径
        ];
    }

    protected function wxPost($url, $data)
    {
        if (!isset($data['appid'])) {
            $data["appid"] = $this->config["app_id"];
        }
//        if (!isset($data['sub_mch_id'])) {
//            $data["sub_mch_id"] = $this->config["sub_mch_id"];
//        }
        if (!isset($data['mch_id']) && !isset($data['mchid'])) {
            $data["mch_id"] = $this->config["mch_id"];
        }
        if (!isset($data['nonce_str'])) {
            $data["nonce_str"] = $this->getNonceStr();
        }

        if (!isset($data['sign'])) {
            $data['sign'] = $this->sign($data);
        }

        $requestXML = $this->array2xml($data);
        $opts       = [
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_SSLCERTTYPE    => 'PEM',
            CURLOPT_SSLCERT        => $this->config['ssl_cert_path'],
            CURLOPT_SSLKEYTYPE     => 'PEM',
            CURLOPT_SSLKEY         => $this->config['ssl_key_path'],
        ];
//        $processResponse = true;
//        if(in_array($url,[self::URL_DOWNLOADBILL,self::URL_DOWNLOAD_FUND_FLOW,self::URL_BATCHQUERYCOMMENT])){
//            $processResponse = false;
//        }

        $content = (new HttpClient())->post(self::API_ENDPOINT . $url, $requestXML, [], $opts);
//        if(!$content) throw new \Exception("Empty response with {$this->requestXML}");

        return $this->xml2array($content);
    }


    private function sign($data, $sign_type = self::SIGNTYPE_MD5)
    {
        ksort($data);
        $string1 = "";
        foreach ($data as $k => $v) {
            if ($v && trim($v) != '') {
                $string1 .= "$k=$v&";
            }
        }
        $stringSignTemp = $string1 . "key=" . $this->config["api_key"];
        if ($sign_type == self::SIGNTYPE_MD5) {
            $sign = strtoupper(md5($stringSignTemp));
        } elseif ($sign_type == self::SIGNTYPE_HMACSHA256) {
            $sign = strtoupper(hash_hmac('sha256', $stringSignTemp, $this->config["api_key"]));
        } else {
            throw new \Exception("Not supported sign type - $sign_type");
        }
        return $sign;
    }

    private function array2xml($array)
    {
        $xml = "<xml>" . PHP_EOL;
        foreach ($array as $k => $v) {
            if ($v && trim($v) != '') {
                $xml .= "<$k><![CDATA[$v]]></$k>" . PHP_EOL;
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    private function xml2array($xml)
    {
        $array = [];
        $tmp   = (array)simplexml_load_string($xml);
        foreach ($tmp as $k => $v) {
            $array[$k] = (string)$v;
        }
        return $array;
    }

    public function getNonceStr()
    {
        return substr(str_shuffle("abcdefghijklmnopqrstuvwxyz0123456789"), 0, 32);
    }
}
